package com.biao.threadPool;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * @description: 手写线程池，最简单化的方式来理解线程池的实现
 * @author:chenwenbiao
 * @createTime:2020/1/17 9:33
 * @Version：1.0
 **/
public class MyFixedSizeThreadPool {

    /**
     * 1. 线程池的构成：队列 线程
      */
    private BlockingQueue<Runnable> queue;

    /**
     * 2. 线程需要管理--容器
     */
    private List<Thread> workers;


    /**
     * work就是一个干活的人，一直等着将代码块运到cpu上执行，代码块就是任务，外面调用时将任务添加进
     */
    private static class Worker extends Thread{
        private MyFixedSizeThreadPool pool;

        public Worker(MyFixedSizeThreadPool pool){
            this.pool = pool;
        }

        /**
         * 每个线程具体的工作
         */
        @Override
        public void run() {
            // 做什么？ ---执行代码--runnable的run方法代码块
            Runnable task = null;

            while (true){
                try {
                    // take()方法会在queue没有东西可以取的时候阻塞，等到队列有任务再往下走
                    task = pool.queue.take();
                } catch (InterruptedException e){
                    e.printStackTrace();
                }

                if(task != null){
                    task.run();
                    System.out.println("线程：" + Thread.currentThread().getName() + "，执行完毕");
                }
            }
        }
    }


    /**
     * 线程池初始化的构造方法
     * @param taskSize 任务的大小，就是排队要排多长，就像买房排队
     * @param poolSize 池子的大小，就是有几个客服人员来同时处理
     */
    public MyFixedSizeThreadPool(int taskSize, int poolSize){
        if(taskSize <= 0 || poolSize <= 0){
            throw new IllegalArgumentException("非法参数！");
        }

        this.queue = new LinkedBlockingDeque<>(taskSize);
        this.workers = Collections.synchronizedList(new ArrayList<>(poolSize));
        /**
         * 开启线程，等着接任务
         */
        for(int i = 0 ; i < poolSize ; i++){
            Worker worker = new Worker(this);
            worker.start();
            workers.add(worker);
        }
    }


    /**
     * 将任务放入仓库
     * @param task
     * @return
     */
    public boolean submit(Runnable task){
        return this.queue.offer(task);
    }


}
